package com.nuonuo.config;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.redisson.Redisson;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RKeys;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.SerializationCodec;
import org.redisson.config.Config;

/**
 * @author duan
 * @version 1.0
 * @date 2023/10/25 15:29
 */
public class RedissonUtils
{
    private final RedissonClient redisson;

    private RMapCache<String, Boolean> mailTestParamMap;

    public static RedissonUtils getInstance(Config config)
    {
        return new RedissonUtils(Redisson.create(config));
    }

    private RedissonUtils(RedissonClient redisson)
    {
        this.redisson = redisson;
    }

//    /**
//     * 功能描述:创建一个限流器
//     *
//     * @param name         限流器名称
//     * @param rate         频率（在频率间隔时间内的次数）
//     * @param rateInterval 频率间隔时间（单位秒）
//     * @return org.redisson.api.RRateLimiter
//     */
//    public RateLimiter createRateLimiter(String name, long rate, long rateInterval)
//    {
//        return RateLimiter.createRateLimiter(redisson, name, rate, rateInterval);
//    }

//    /**
//     * 功能描述:获取限流器（在确定redis中有该限流器时使用）
//     *
//     * @param name         限流器名称
//     * @param rate         频率（在频率间隔时间内的次数）
//     * @param rateInterval 频率间隔时间（单位秒）
//     * @return com.aisino.elin.common.redisson.RateLimiter
//     * @createtime 2018/7/12 15:41
//     * @author Jianhui Lu
//     */
//    public RateLimiter getRateLimiter(String name, long rate, long rateInterval)
//    {
//        return RateLimiter.getRateLimiter(redisson, name, rate, rateInterval);
//    }

//
//    /**
//     * 功能描述:设置限流器频率
//     *
//     * @param rateLimiter
//     * @param rate
//     * @param rateInterval
//     * @return boolean
//     * @createtime 2018/7/16 17:08
//     * @author Jianhui Lu
//     */
//    public boolean setRate(RateLimiter rateLimiter, long rate, long rateInterval)
//    {
//        RLock rLock = redisson.getLock("Lock-" + rateLimiter.getName());
//        if (!rLock.tryLock())
//        {
//            //拿不到锁就证明，已由其它线程在设置限流参数
//            return true;
//        }
//
//        boolean isSuccess = rateLimiter.setRate(rate, rateInterval);
//
//        rLock.unlock();
//        return isSuccess;
//    }

    /**
     * 功能描述:判断是否存在某个名称的队列
     *
     * @param name 队列名称
     * @return boolean
     * @createtime 2018/7/11 17:44
     * @author Jianhui Lu
     */
    public boolean isExistsQueue(String name)
    {
        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
        if (isTest == null ? false : isTest)
        {
            Boolean isExistsQueue = getMailTestParamByName(TestPrarmEnum.isExistsQueue.name());
            if (isExistsQueue != null)
            {
                return isExistsQueue;
            }
        }
        return redisson.getBlockingDeque(name).isExists();
    }


    /**
     * 功能描述:判断队列中是否存在改值
     *
     * @param queueName 队列名称
     * @param value
     * @return boolean
     * @createtime 2018/7/17 15:23
     * @author Jianhui Lu
     */
    public boolean isContainInQueueString(String queueName, String value)
    {
        return getQueueString(queueName).contains(value);
    }

//    /**
//     * 功能描述:TODO
//     *
//     * @param rateLimiter
//     * @return boolean
//     * @createtime 2018/7/17 10:31
//     * @author Jianhui Lu
//     */
//    public boolean tryAcquire(RateLimiter rateLimiter)
//    {
//        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
//        if (isTest == null ? false : isTest)
//        {
//            if ("RateLimiter-Mail".equals(rateLimiter.getName()))
//            {
//                Boolean isAcquireMail = getMailTestParamByName(TestPrarmEnum.isAcquireMail.name());
//                if (isAcquireMail != null)
//                {
//                    return isAcquireMail;
//                }
//            }
//            else
//            {
//                Boolean isAcquireMailAddress = getMailTestParamByName(TestPrarmEnum.isAcquireMailAddress.name());
//                if (isAcquireMailAddress != null)
//                {
//                    return isAcquireMailAddress;
//                }
//            }
//        }
//
//        boolean isAcquire = false;
//        try
//        {
//            isAcquire = rateLimiter.tryAcquire();
//        }
//        catch (Exception e)
//        {
//            LogUtils.outLogInfoLocal("避免误删限流器，而启动的补偿创建限流器：" + rateLimiter.getName());
//            rateLimiter.createRateLimiter(redisson);
//            try
//            {
//                isAcquire = rateLimiter.tryAcquire();
//            }
//            catch (Exception e1)
//            {
//                //不做处理
//            }
//        }
//
//        return isAcquire;
//    }
//
//    /**
//     * 功能描述:获得（堵塞型）
//     *
//     * @param rateLimiter
//     * @return void
//     * @createtime 2018/7/23 17:57
//     * @author Jianhui Lu
//     */
//    public void acquire(RateLimiter rateLimiter)
//    {
//        try
//        {
//            rateLimiter.acquire();
//        }
//        catch (Exception e)
//        {
//            rateLimiter.createRateLimiter(redisson);
//            try
//            {
//                rateLimiter.acquire();
//            }
//            catch (Exception e1)
//            {
//                //不做处理
//            }
//        }
//    }

    /**
     * 功能描述:获取一个存储序列化的队列
     *
     * @param name
     * @return org.redisson.api.RBlockingDeque<V>
     * @createtime 2018/7/11 18:11
     * @author Jianhui Lu
     */
    public <V> RBlockingDeque<V> getQueueSerializable(String name)
    {
        return redisson.getBlockingDeque(name, new SerializationCodec());
    }

    /**
     * 功能描述:获取一个字符的队列
     *
     * @param name
     * @return org.redisson.api.RBlockingDeque<V>
     * @createtime 2018/7/12 14:44
     * @author Jianhui Lu
     */
    public <V> RBlockingDeque<V> getQueueString(String name)
    {
        return redisson.getBlockingDeque(name, StringCodec.INSTANCE);
    }

    /**
     * 功能描述:获取一个默认的Map
     *
     * @param name
     * @return org.redisson.api.RMapCache<K,V>
     * @createtime 2018/7/13 14:54
     * @author Jianhui Lu
     */
    public <K, V> RMapCache<K, V> getMap(String name)
    {
        return redisson.getMapCache(name);
    }

    /**
     * 功能描述:获取一个字符的Map
     *
     * @param name
     * @return org.redisson.api.RMapCache<K,V>
     * @createtime 2018/7/13 14:54
     * @author Jianhui Lu
     */
    public <K, V> RMapCache<K, V> getMapString(String name)
    {
        return redisson.getMapCache(name, StringCodec.INSTANCE);
    }

    public RKeys getKeys()
    {
        return redisson.getKeys();
    }

    /**
     * 功能描述:TODO
     *
     * @param
     * @return boolean
     * @createtime 2018/7/17 13:30
     * @author Jianhui Lu
     */
    public boolean isStopDealWithMail()
    {
        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
        if (isTest == null ? false : isTest)
        {
            Boolean isStopDealWithMail = getMailTestParamByName(TestPrarmEnum.isStopDealWithMail.name());
            if (isStopDealWithMail != null)
            {
                return isStopDealWithMail;
            }
        }

        return false;
    }

    public boolean isStopDeleteRateLimiter()
    {
        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
        if (isTest == null ? false : isTest)
        {
            Boolean isStopDeleteRateLimiter = getMailTestParamByName(TestPrarmEnum.isStopDeleteRateLimiter.name());
            if (isStopDeleteRateLimiter != null)
            {
                return isStopDeleteRateLimiter;
            }
        }

        return false;
    }

    public boolean isStopMonitorMailQueue()
    {
        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
        if (isTest == null ? false : isTest)
        {
            Boolean isStopDeleteRateLimiter = getMailTestParamByName(TestPrarmEnum.isStopMonitorMailQueue.name());
            if (isStopDeleteRateLimiter != null)
            {
                return isStopDeleteRateLimiter;
            }
        }

        return false;
    }

    public boolean isSimulateMail()
    {
        Boolean isTest = getMailTestParamByName(TestPrarmEnum.isTest.name());
        if (isTest == null ? false : isTest)
        {
            Boolean isSimulateMail = getMailTestParamByName(TestPrarmEnum.isSimulateMail.name());
            if (isSimulateMail != null)
            {
                return isSimulateMail;
            }
        }

        return false;
    }

    public boolean tryLock(String lockName)
    {
        return redisson.getLock(lockName).tryLock();
    }

    public RedissonClient getRedissonClient()
    {
        return redisson;
    }



    /****************************************************************************************************
     * 以下为测试用代码
     *
     * **************************************************************************************************
     */
    /**
     * 功能描述:邮件测试参数Map（只为邮件限流测试服务）
     *
     * @param
     * @return org.redisson.api.RMapCache
     * @createtime 2018/7/17 10:37
     * @author Jianhui Lu
     */
    private RMapCache<String, Boolean> getMailTestParamMap()
    {
        if (this.mailTestParamMap != null)
        {
            return this.mailTestParamMap;
        }

        this.mailTestParamMap = this.getMap("Map-ControlMailFlowParamForTest");
        return this.mailTestParamMap;
    }

    private Boolean getMailTestParamByName(String name)
    {
        return this.getMailTestParamMap().get(name);
    }

    public void shutdown() {
        if(redisson!=null){
            redisson.shutdown();
        }
    }

    private enum TestPrarmEnum
    {
        /**
         * 类型
         */
        isTest,
        isExistsQueue,
        isAcquireMailAddress,
        isAcquireMail,
        isStopDeleteRateLimiter,
        isStopDealWithMail,
        isStopMonitorMailQueue,
        isSimulateMail;

        private static final Map<String, TestPrarmEnum> VALUE_MAP;

        static
        {
            Map<String, TestPrarmEnum> map = new HashMap<>();
            for (TestPrarmEnum testPrarmEnum : TestPrarmEnum.values())
            {
                map.put(testPrarmEnum.name(), testPrarmEnum);
            }

            VALUE_MAP = Collections.unmodifiableMap(map);
        }

        public static TestPrarmEnum getByValue(String value)
        {
            return VALUE_MAP.get(value);
        }
    }
}
